Skip to content

feat(hooks): add a Cline file-based hooks adapter - #2628

Merged
dyoshikawa merged 4 commits into
mainfrom
resolve-issue-2405-cline-hooks
Aug 7, 2026
Merged

feat(hooks): add a Cline file-based hooks adapter#2628
dyoshikawa merged 4 commits into
mainfrom
resolve-issue-2405-cline-hooks

Conversation

@dyoshikawa

Copy link
Copy Markdown
Owner

Adds a cline hooks target for Cline's file-based hooks, following the maintainer comment that reversed the earlier deferral.

Upstream re-verified from source before implementing (the docs page at docs.cline.bot/features/hooks now redirects to the SDK plugins page, which describes a different surface):

Deviation from the mapping in the issue comment: TaskError and SessionShutdown do not exist. VALID_HOOK_TYPES is exactly TaskStart, TaskResume, TaskCancel, TaskComplete, PreToolUse, PostToolUse, UserPromptSubmit, Notification, PreCompact, so afterError and sessionEnd are left unmapped rather than pointed at names Cline would reject. The other seven mappings from the comment match upstream and are implemented. TaskResume/TaskCancel have no canonical counterpart and stay unmapped.

Ownership. The hooks directory is where users hand-author their own hooks and the filenames are fixed by the contract, so every generated script carries a rulesync-owned: cline-hooks marker and a script without it is never overwritten. Because the hooks feature reconciles only its single settable path, a script whose event is removed is rewritten as a no-op instead of being stranded with live behavior; the manifest rulesync-hooks.json records which events rulesync generated.

New shared infrastructure: AiFile.getFileMode() (default undefined) plus a chmod in writeAiFiles, applied even when the content write is skipped so an interrupted run cannot leave a hook without its executable bit. No-op on Windows.

Matchers are not supported (the wrapper is a plain shell script with no payload parser) and import is unsupported, both declared in the factory meta. Unit tests cover the mapping, the override block, multi-command ordering, marker-guarded collision, no-op retraction and the executable bit; e2e-hooks covers the target at both scopes.

The issue's other gaps — global modular rules, the required agent description, and the deprecated .clinerules handling — are not addressed here.

Part of #2405

🤖 Generated with Claude Code

Cline resolves one executable per lifecycle event from .clinerules/hooks (project) or ~/Documents/Cline/Hooks (global), named exactly after the event and answering with a JSON result on stdout. Emit a wrapper script per configured event in both the POSIX and PowerShell spellings, plus a manifest of what rulesync owns, and add the file-mode plumbing the executable bit needs.
Wire the adapter into the processor registry, the e2e generate matrix at both scopes, the derived gitignore entry and the generated support tables, and document the surface in file-formats.md.
Restrict the manifest's event list to the names this adapter emits, so a committed manifest cannot make generate write an executable anywhere else. Pass each command to bash -c as a quoted argument instead of splicing it into the wrapper, check its syntax so an unparseable command reports an error rather than cancelling, and strip control characters from the JSON result, which a tab or carriage return in a command's stderr used to make unparseable. Delete the marked scripts when the target is dropped, warn on a hand-authored collision, gitignore the generated script names, and only restore a missing executable bit rather than resetting a mode the user tightened.
Reusing getAuxiliaryFiles for the deletion pass made every adapter's extra files deletion candidates, and Codex CLI returns the user's shared .codex/config.toml there — a --delete run with no hooks source would have removed it. Give the sweep its own getDeletableAuxiliaryFiles hook, implemented only by the Cline adapter, and filter it through isDeletable.
@dyoshikawa
dyoshikawa merged commit a07338d into main Aug 7, 2026
9 checks passed
@dyoshikawa
dyoshikawa deleted the resolve-issue-2405-cline-hooks branch August 7, 2026 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants